home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / manageme / tcpdump-.7 / tcpdump- / tcpdump-richard-1.7 / tcpdump-3.0 / addrtoname.c next >
Encoding:
C/C++ Source or Header  |  1995-04-12  |  17.0 KB  |  776 lines

  1. /*
  2.  * Copyright (c) 1990, 1991, 1992, 1993, 1994
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  *
  21.  *  Internet, ethernet, port, and protocol string to address
  22.  *  and address to string conversion routines
  23.  */
  24. #ifndef lint
  25. static char rcsid[] =
  26.     "@(#) $Header: addrtoname.c,v 1.37 94/06/16 00:42:28 mccanne Exp $ (LBL)";
  27. #endif
  28.  
  29. #include <sys/types.h>
  30. #include <sys/socket.h>
  31. #include <sys/time.h>
  32.  
  33. #include <net/if.h>
  34.  
  35. #include <netinet/in.h>
  36. #include <netinet/if_ether.h>
  37.  
  38. #include <arpa/inet.h>
  39.  
  40. #include <ctype.h>
  41. #include <netdb.h>
  42. #include <pcap.h>
  43. #include <pcap-namedb.h>
  44. #include <signal.h>
  45. #include <stdio.h>
  46. #include <string.h>
  47. #ifdef __STDC__
  48. #include <stdlib.h>
  49. #endif
  50. #include <unistd.h>
  51.  
  52. #include "interface.h"
  53. #include "addrtoname.h"
  54. #include "llc.h"
  55.  
  56. static SIGRET nohostname(int);
  57. #ifdef ETHER_SERVICE
  58. struct ether_addr;
  59. extern int ether_ntohost(char *, struct ether_addr *);
  60. #endif
  61.  
  62. /*
  63.  * hash tables for whatever-to-name translations
  64.  */
  65.  
  66. #define HASHNAMESIZE 4096
  67.  
  68. struct hnamemem {
  69.     u_int32 addr;
  70.     char *name;
  71.     struct hnamemem *nxt;
  72. };
  73.  
  74. struct hnamemem hnametable[HASHNAMESIZE];
  75. struct hnamemem tporttable[HASHNAMESIZE];
  76. struct hnamemem uporttable[HASHNAMESIZE];
  77. struct hnamemem eprototable[HASHNAMESIZE];
  78. struct hnamemem dnaddrtable[HASHNAMESIZE];
  79. struct hnamemem llcsaptable[HASHNAMESIZE];
  80.  
  81. struct enamemem {
  82.     u_short e_addr0;
  83.     u_short e_addr1;
  84.     u_short e_addr2;
  85.     char *e_name;
  86.     u_char *e_nsap;            /* used only for nsaptable[] */
  87.     struct enamemem *e_nxt;
  88. };
  89.  
  90. struct enamemem enametable[HASHNAMESIZE];
  91. struct enamemem nsaptable[HASHNAMESIZE];
  92.  
  93. struct protoidmem {
  94.     u_long p_oui;
  95.     u_short p_proto;
  96.     char *p_name;
  97.     struct protoidmem *p_nxt;
  98. };
  99.  
  100. struct protoidmem protoidtable[HASHNAMESIZE];
  101.  
  102. /*
  103.  * A faster replacement for inet_ntoa().
  104.  */
  105. char *
  106. intoa(u_int32 addr)
  107. {
  108.     register char *cp;
  109.     register u_int byte;
  110.     register int n;
  111.     static char buf[sizeof(".xxx.xxx.xxx.xxx")];
  112.  
  113.     NTOHL(addr);
  114.     cp = &buf[sizeof buf];
  115.     *--cp = '\0';
  116.  
  117.     n = 4;
  118.     do {
  119.         byte = addr & 0xff;
  120.         *--cp = byte % 10 + '0';
  121.         byte /= 10;
  122.         if (byte > 0) {
  123.             *--cp = byte % 10 + '0';
  124.             byte /= 10;
  125.             if (byte > 0)
  126.                 *--cp = byte + '0';
  127.         }
  128.         *--cp = '.';
  129.         addr >>= 8;
  130.     } while (--n > 0);
  131.  
  132.     return cp + 1;
  133. }
  134.  
  135. static u_int32 f_netmask;
  136. static u_int32 f_localnet;
  137. static u_int32 netmask;
  138.  
  139. /*
  140.  * "getname" is written in this atrocious way to make sure we don't
  141.  * wait forever while trying to get hostnames from yp.
  142.  */
  143. #include <setjmp.h>
  144.  
  145. jmp_buf getname_env;
  146.  
  147. static SIGRET
  148. nohostname(int signo)
  149. {
  150.     longjmp(getname_env, 1);
  151. }
  152.  
  153. /*
  154.  * Return a name for the IP address pointed to by ap.  This address
  155.  * is assumed to be in network byte order.
  156.  */
  157. char *
  158. getname(const u_char *ap)
  159. {
  160.     register struct hostent *hp;
  161.     register char *cp;
  162.     u_int32 addr;
  163.     static struct hnamemem *p;        /* static for longjmp() */
  164.  
  165. #ifndef TCPDUMP_ALIGN
  166.     addr = *(const u_int32 *)ap;
  167. #else
  168.     /*
  169.      * Deal with alignment.
  170.      */
  171.     switch ((int)ap & 3) {
  172.  
  173.     case 0:
  174.         addr = *(u_int32 *)ap;
  175.         break;
  176.  
  177.     case 2:
  178. #if BYTE_ORDER == LITTLE_ENDIAN
  179.         addr = ((u_int32)*(u_short *)(ap + 2) << 16) |
  180.             (u_int32)*(u_short *)ap;
  181. #else
  182.         addr = ((u_int32)*(u_short *)ap << 16) |
  183.             (u_int32)*(u_short *)(ap + 2);
  184. #endif
  185.         break;
  186.  
  187.     default:
  188. #if BYTE_ORDER == LITTLE_ENDIAN
  189.         addr = ((u_int32)ap[0] << 24) |
  190.             ((u_int32)ap[1] << 16) |
  191.             ((u_int32)ap[2] << 8) |
  192.             (u_int32)ap[3];
  193. #else
  194.         addr = ((u_int32)ap[3] << 24) |
  195.             ((u_int32)ap[2] << 16) |
  196.             ((u_int32)ap[1] << 8) |
  197.             (u_int32)ap[0];
  198. #endif
  199.         break;
  200.     }
  201. #endif
  202.     p = &hnametable[addr & (HASHNAMESIZE-1)];
  203.     for (; p->nxt; p = p->nxt) {
  204.         if (p->addr == addr)
  205.             return (p->name);
  206.     }
  207.     p->addr = addr;
  208.     p->nxt = (struct hnamemem *)calloc(1, sizeof (*p));
  209.  
  210.     /*
  211.      * Only print names when:
  212.      *    (1) -n was not given.
  213.      *    (2) Address is foreign and -f was given.  If -f was not
  214.      *        present, f_netmask and f_local are 0 and the second
  215.      *        test will succeed.
  216.      *    (3) The host portion is not 0 (i.e., a network address).
  217.      *    (4) The host portion is not broadcast.
  218.      */
  219.     if (!nflag && (addr & f_netmask) == f_localnet
  220.         && (addr &~ netmask) != 0 && (addr | netmask) != 0xffffffff) {
  221.         if (!setjmp(getname_env)) {
  222.             (void)signal(SIGALRM, nohostname);
  223.             (void)alarm(20);
  224.             hp = gethostbyaddr((char *)&addr, 4, AF_INET);
  225.             (void)alarm(0);
  226.             if (hp) {
  227.                 char *dotp;
  228.  
  229.                 p->name = savestr(hp->h_name);
  230.                 if (Nflag) {
  231.                     /* Remove domain qualifications */
  232.                     dotp = strchr(p->name, '.');
  233.                     if (dotp)
  234.                         *dotp = 0;
  235.                 }
  236.                 return (p->name);
  237.             }
  238.         }
  239.     }
  240.     cp = intoa(addr);
  241.     p->name = savestr(cp);
  242.     return (p->name);
  243. }
  244.  
  245. static char hex[] = "0123456789abcdef";
  246.  
  247.  
  248. /* Find the hash node that corresponds the ether address 'ep'. */
  249.  
  250. static inline struct enamemem *
  251. lookup_emem(const u_char *ep)
  252. {
  253.     register u_int i, j, k;
  254.     struct enamemem *tp;
  255.  
  256.     k = (ep[0] << 8) | ep[1];
  257.     j = (ep[2] << 8) | ep[3];
  258.     i = (ep[4] << 8) | ep[5];
  259.  
  260.     tp = &enametable[(i ^ j) & (HASHNAMESIZE-1)];
  261.     while (tp->e_nxt)
  262.         if (tp->e_addr0 == i &&
  263.             tp->e_addr1 == j &&
  264.             tp->e_addr2 == k)
  265.             return tp;
  266.         else
  267.             tp = tp->e_nxt;
  268.     tp->e_addr0 = i;
  269.     tp->e_addr1 = j;
  270.     tp->e_addr2 = k;
  271.     tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
  272.  
  273.     return tp;
  274. }
  275.  
  276. /* Find the hash node that corresponds the NSAP 'nsap'. */
  277.  
  278. static inline struct enamemem *
  279. lookup_nsap(register const u_char *nsap)
  280. {
  281.     register u_int i, j, k;
  282.     int nlen = *nsap;
  283.     struct enamemem *tp;
  284.     const u_char *ensap = nsap + nlen - 6;
  285.  
  286.     if (nlen > 6) {
  287.         k = (ensap[0] << 8) | ensap[1];
  288.         j = (ensap[2] << 8) | ensap[3];
  289.         i = (ensap[4] << 8) | ensap[5];
  290.     }
  291.     else
  292.         i = j = k = 0;
  293.  
  294.     tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)];
  295.     while (tp->e_nxt)
  296.         if (tp->e_addr0 == i &&
  297.             tp->e_addr1 == j &&
  298.             tp->e_addr2 == k &&
  299.             tp->e_nsap[0] == nlen &&
  300.             bcmp((char *)&(nsap[1]),
  301.             (char *)&(tp->e_nsap[1]), nlen) == 0)
  302.             return tp;
  303.         else
  304.             tp = tp->e_nxt;
  305.     tp->e_addr0 = i;
  306.     tp->e_addr1 = j;
  307.     tp->e_addr2 = k;
  308.     tp->e_nsap = (u_char *) calloc(1, nlen + 1);
  309.     bcopy(nsap, tp->e_nsap, nlen + 1);
  310.     tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
  311.  
  312.     return tp;
  313. }
  314.  
  315. /* Find the hash node that corresponds the protoid 'pi'. */
  316.  
  317. static inline struct protoidmem *
  318. lookup_protoid(const u_char *pi)
  319. {
  320.     register u_int i, j;
  321.     struct protoidmem *tp;
  322.  
  323.     /* 5 octets won't be aligned */
  324.     i = (((pi[0] << 8) + pi[1]) << 8) + pi[2];
  325.     j =   (pi[3] << 8) + pi[4];
  326.     /* XXX should be endian-insensitive, but do big-endian testing  XXX */
  327.  
  328.     tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)];
  329.     while (tp->p_nxt)
  330.         if (tp->p_oui == i && tp->p_proto == j)
  331.             return tp;
  332.         else
  333.             tp = tp->p_nxt;
  334.     tp->p_oui = i;
  335.     tp->p_proto = j;
  336.     tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp));
  337.  
  338.     return tp;
  339. }
  340.  
  341. char *
  342. etheraddr_string(register const u_char *ep)
  343. {
  344.     register u_int i, j;
  345.     register char *cp;
  346.     register struct enamemem *tp;
  347.  
  348.     tp = lookup_emem(ep);
  349.     if (tp->e_name)
  350.         return (tp->e_name);
  351. #ifdef ETHER_SERVICE
  352.     if (!nflag) {
  353.         char buf[128];
  354.         if (ether_ntohost(buf, (struct ether_addr *)ep) == 0) {
  355.             tp->e_name = savestr(buf);
  356.             return (tp->e_name);
  357.         }
  358.     }
  359. #endif
  360.     tp->e_name = cp = (char *)malloc(sizeof("00:00:00:00:00:00"));
  361.  
  362.     if ((j = *ep >> 4) != 0)
  363.         *cp++ = hex[j];
  364.     *cp++ = hex[*ep++ & 0xf];
  365.     for (i = 5; (int)--i >= 0;) {
  366.         *cp++ = ':';
  367.         if ((j = *ep >> 4) != 0)
  368.             *cp++ = hex[j];
  369.         *cp++ = hex[*ep++ & 0xf];
  370.     }
  371.     *cp = '\0';
  372.     return (tp->e_name);
  373. }
  374.  
  375. char *
  376. etherproto_string(u_short port)
  377. {
  378.     register char *cp;
  379.     register struct hnamemem *tp;
  380.     register u_long i = port;
  381.  
  382.     for (tp = &eprototable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
  383.         if (tp->addr == i)
  384.             return (tp->name);
  385.  
  386.     tp->name = cp = (char *)malloc(sizeof("0000"));
  387.     tp->addr = i;
  388.     tp->nxt = (struct hnamemem *)calloc(1, sizeof (*tp));
  389.  
  390.     NTOHS(port);
  391.     *cp++ = hex[port >> 12 & 0xf];
  392.     *cp++ = hex[port >> 8 & 0xf];
  393.     *cp++ = hex[port >> 4 & 0xf];
  394.     *cp++ = hex[port & 0xf];
  395.     *cp++ = '\0';
  396.     return (tp->name);
  397. }
  398.  
  399. char *
  400. protoid_string(register const u_char *pi)
  401. {
  402.     register u_int i, j;
  403.     register char *cp;
  404.     register struct protoidmem *tp;
  405.  
  406.     tp = lookup_protoid(pi);
  407.     if (tp->p_name)
  408.         return tp->p_name;
  409.  
  410.     tp->p_name = cp = (char *)malloc(sizeof("00:00:00:00:00"));
  411.  
  412.     if ((j = *pi >> 4) != 0)
  413.         *cp++ = hex[j];
  414.     *cp++ = hex[*pi++ & 0xf];
  415.     for (i = 4; (int)--i >= 0;) {
  416.         *cp++ = ':';
  417.         if ((j = *pi >> 4) != 0)
  418.             *cp++ = hex[j];
  419.         *cp++ = hex[*pi++ & 0xf];
  420.     }
  421.     *cp = '\0';
  422.     return (tp->p_name);
  423. }
  424.  
  425. char *
  426. llcsap_string(u_char sap)
  427. {
  428.     register char *cp;
  429.     register struct hnamemem *tp;
  430.     register u_long i = sap;
  431.  
  432.     for (tp = &llcsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
  433.         if (tp->addr == i)
  434.             return (tp->name);
  435.  
  436.     tp->name = cp = (char *)malloc(sizeof("sap 00"));
  437.     tp->addr = i;
  438.     tp->nxt = (struct hnamemem *)calloc(1, sizeof (*tp));
  439.  
  440.     (void)strcpy(cp, "sap ");
  441.     cp += strlen(cp);
  442.     *cp++ = hex[sap >> 4 & 0xf];
  443.     *cp++ = hex[sap & 0xf];
  444.     *cp++ = '\0';
  445.     return (tp->name);
  446. }
  447.  
  448. char *
  449. isonsap_string(const u_char *nsap)
  450. {
  451.     register u_int i, nlen = nsap[0];
  452.     register char *cp;
  453.     register struct enamemem *tp;
  454.  
  455.     tp = lookup_nsap(nsap);
  456.     if (tp->e_name)
  457.         return tp->e_name;
  458.  
  459.     tp->e_name = cp = (char *)malloc(nlen * 2 + 2);
  460.  
  461.     nsap++;
  462.     *cp++ = '/';
  463.     for (i = nlen; (int)--i >= 0;) {
  464.         *cp++ = hex[*nsap >> 4];
  465.         *cp++ = hex[*nsap++ & 0xf];
  466.     }
  467.     *cp = '\0';
  468.     return (tp->e_name);
  469. }
  470.  
  471. char *
  472. tcpport_string(u_short port)
  473. {
  474.     register struct hnamemem *tp;
  475.     register u_long i = port;
  476.  
  477.     for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
  478.         if (tp->addr == i)
  479.             return (tp->name);
  480.  
  481.     tp->name = (char *)malloc(sizeof("00000"));
  482.     tp->addr = i;
  483.     tp->nxt = (struct hnamemem *)calloc(1, sizeof (*tp));
  484.  
  485.     (void)sprintf(tp->name, "%d", i);
  486.     return (tp->name);
  487. }
  488.  
  489. char *
  490. udpport_string(register u_short port)
  491. {
  492.     register struct hnamemem *tp;
  493.     register u_long i = port;
  494.  
  495.     for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
  496.         if (tp->addr == i)
  497.             return (tp->name);
  498.  
  499.     tp->name = (char *)malloc(sizeof("00000"));
  500.     tp->addr = i;
  501.     tp->nxt = (struct hnamemem *)calloc(1, sizeof(*tp));
  502.  
  503.     (void)sprintf(tp->name, "%d", i);
  504.  
  505.     return (tp->name);
  506. }
  507.  
  508. static void
  509. init_hostarray(char *fname)
  510. {
  511. FILE *f;
  512. char line[128], *s, *name, *dotp;
  513. u_int32 addr;
  514. int32 v;
  515. struct hnamemem *p;
  516.  
  517.     if (fname == NULL || !strcmp(fname, "-") || 
  518.         (f = fopen(fname, "r")) == NULL)
  519.         return;
  520.     clearerr(f);
  521.     while (!feof(f) && !ferror(f))
  522.     {
  523.         name = NULL;
  524.         if (fgets(line, sizeof(line), f) == NULL)
  525.             continue;
  526.         if ((s = strchr(line, '#')) != NULL)
  527.             *s = '\0';
  528.         if ((s = strtok(line, " \t\n")) == NULL)
  529.             continue;
  530.         if ((v = inet_addr(s)) == -1)
  531.             continue;
  532.         addr = v;
  533.         /* take the shortest name from the list */
  534.         while ((s = strtok(NULL, " \t\n")) != NULL)
  535.             if (name == NULL || strlen(s) < strlen(name))
  536.                 name = s;
  537.         if (name != NULL)
  538.         {
  539.             p = &hnametable[addr & (HASHNAMESIZE-1)];
  540.             for (; p->nxt; p = p->nxt) {
  541.                 if (p->addr == addr)
  542.                     break;
  543.             }
  544.             if (p->nxt == NULL)
  545.             {
  546.                 p->nxt = (struct hnamemem *)calloc(1, sizeof (*p));
  547.                 p->addr = addr;
  548.                 p->name = savestr(name);
  549.                 if (Nflag) {
  550.                     /* Remove domain qualifications */
  551.                     dotp = strchr(p->name, '.');
  552.                     if (dotp)
  553.                         *dotp = 0;
  554.                 }
  555.             }
  556.         }
  557.     }
  558.     fclose(f);
  559. }
  560.  
  561. static void
  562. init_servarray(void)
  563. {
  564.     struct servent *sv;
  565.     register struct hnamemem *table;
  566.     register int i;
  567.  
  568.     while ((sv = getservent()) != NULL) {
  569.         int port = ntohs(sv->s_port);
  570.         i = port & (HASHNAMESIZE-1);
  571.         if (strcmp(sv->s_proto, "tcp") == 0)
  572.             table = &tporttable[i];
  573.         else if (strcmp(sv->s_proto, "udp") == 0)
  574.             table = &uporttable[i];
  575.         else
  576.             continue;
  577.  
  578.         while (table->name)
  579.             table = table->nxt;
  580.         if (nflag) {
  581.             char buf[32];
  582.  
  583.             (void)sprintf(buf, "%d", port);
  584.             table->name = savestr(buf);
  585.         } else
  586.             table->name = savestr(sv->s_name);
  587.         table->addr = port;
  588.         table->nxt = (struct hnamemem *)calloc(1, sizeof(*table));
  589.     }
  590.     endservent();
  591. }
  592.  
  593. /*XXX from libbpfc.a */
  594. extern struct eproto {
  595.     char *s;
  596.     u_short p;
  597. } eproto_db[];
  598.  
  599. static void
  600. init_eprotoarray(void)
  601. {
  602.     register int i;
  603.     register struct hnamemem *table;
  604.  
  605.     for (i = 0; eproto_db[i].s; i++) {
  606.         int j = ntohs(eproto_db[i].p) & (HASHNAMESIZE-1);
  607.         table = &eprototable[j];
  608.         while (table->name)
  609.             table = table->nxt;
  610.         table->name = eproto_db[i].s;
  611.         table->addr = ntohs(eproto_db[i].p);
  612.         table->nxt = (struct hnamemem *)calloc(1, sizeof(*table));
  613.     }
  614. }
  615.  
  616. /*
  617.  * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet
  618.  * types.
  619.  */
  620. static void
  621. init_protoidarray(void)
  622. {
  623.     register int i;
  624.     register struct protoidmem *tp;
  625.     u_char protoid[5];
  626.  
  627.     protoid[0] = 0;
  628.     protoid[1] = 0;
  629.     protoid[2] = 0;
  630.     for (i = 0; eproto_db[i].s; i++) {
  631.         u_short etype = htons(eproto_db[i].p);
  632.         bcopy((char *)&etype, (char *)&protoid[3], 2);
  633.         tp = lookup_protoid(protoid);
  634.         tp->p_name = savestr(eproto_db[i].s);
  635.     }
  636. }
  637.  
  638. static struct etherlist {
  639.     u_char addr[6];
  640.     char *name;
  641. } etherlist[] = {
  642.     {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" },
  643.     {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL }
  644. };
  645.  
  646. /*
  647.  * Initialize the ethers hash table.  We take two different approaches
  648.  * depending on whether or not the system provides the ethers name
  649.  * service.  If it does, we just wire in a few names at startup,
  650.  * and etheraddr_string() fills in the table on demand.  If it doesn't,
  651.  * then we suck in the entire /etc/ethers file at startup.  The idea
  652.  * is that parsing the local file will be fast, but spinning through
  653.  * all the ethers entries via NIS & next_etherent might be very slow.
  654.  *
  655.  * XXX pcap_next_etherent doesn't belong in the pcap interface, but
  656.  * since the pcap module already does name-to-address translation,
  657.  * it's already does most of the work for the ethernet address-to-name
  658.  * translation, so we just pcap_next_etherent as a convenience.
  659.  */
  660. static void
  661. init_etherarray(void)
  662. {
  663.     register struct etherlist *el;
  664.     register struct enamemem *tp;
  665. #ifndef ETHER_SERVICE
  666.     register struct pcap_etherent *ep;
  667.     register FILE *fp;
  668.  
  669.     /* Suck in entire ethers file */
  670.     fp = fopen(PCAP_ETHERS_FILE, "r");
  671.     if (fp != NULL) {
  672.         while ((ep = pcap_next_etherent(fp)) != NULL) {
  673.             tp = lookup_emem(ep->addr);
  674.             tp->e_name = savestr(ep->name);
  675.         }
  676.         (void)fclose(fp);
  677.     }
  678. #endif
  679.  
  680.     /* Hardwire some ethernet names */
  681.     for (el = etherlist; el->name != NULL; ++el) {
  682. #ifdef ETHER_SERVICE
  683.                 /* Use yp/nis version of name if available */
  684.         char wrk[256];
  685.                 if (ether_ntohost(wrk, (struct ether_addr *)el->addr) == 0) {
  686.             tp = lookup_emem(el->addr);
  687.                         tp->e_name = savestr(wrk);
  688.         }
  689. #else
  690.         /* install if not already present */
  691.         tp = lookup_emem(el->addr);
  692.         if (tp->e_name == NULL)
  693.             tp->e_name = el->name;
  694. #endif
  695.  
  696.     }
  697. }
  698.  
  699. static struct token llcsap_db[] = {
  700.     { LLCSAP_NULL,        "null" },
  701.     { LLCSAP_8021B_I,    "802.1b-gsap" },
  702.     { LLCSAP_8021B_G,    "802.1b-isap" },
  703.     { LLCSAP_IP,        "ip-sap" },
  704.     { LLCSAP_PROWAYNM,    "proway-nm" },
  705.     { LLCSAP_8021D,        "802.1d" },
  706.     { LLCSAP_RS511,        "eia-rs511" },
  707.     { LLCSAP_ISO8208,    "x.25/llc2" },
  708.     { LLCSAP_PROWAY,    "proway" },
  709.     { LLCSAP_ISONS,        "iso-clns" },
  710.     { LLCSAP_GLOBAL,    "global" },
  711.     { 0,            NULL }
  712. };
  713.  
  714. static void
  715. init_llcsaparray(void)
  716. {
  717.     register int i;
  718.     register struct hnamemem *table;
  719.  
  720.     for (i = 0; llcsap_db[i].s != NULL; i++) {
  721.         table = &llcsaptable[llcsap_db[i].v];
  722.         while (table->name)
  723.             table = table->nxt;
  724.         table->name = llcsap_db[i].s;
  725.         table->addr = llcsap_db[i].v;
  726.         table->nxt = (struct hnamemem *)calloc(1, sizeof(*table));
  727.     }
  728. }
  729.  
  730. /*
  731.  * Initialize the address to name translation machinery.  We map all
  732.  * non-local IP addresses to numeric addresses if fflag is true (i.e.,
  733.  * to prevent blocking on the nameserver).  localnet is the IP address
  734.  * of the local network.  mask is its subnet mask.
  735.  */
  736. void
  737. init_addrtoname(int fflag, u_int32 localnet, u_int32 mask, char *fname)
  738. {
  739.     netmask = mask;
  740.     if (fflag) {
  741.         f_localnet = localnet;
  742.         f_netmask = mask;
  743.     }
  744.  
  745.     /* Simplest way to suppress names */
  746.     if (nflag)
  747.         return;
  748.  
  749.     init_hostarray(fname);
  750.     init_etherarray();
  751.     init_servarray();
  752.     init_eprotoarray();
  753.     init_llcsaparray();
  754.     init_protoidarray();
  755. }
  756.  
  757. char *
  758. dnaddr_string(u_short dnaddr)
  759. {
  760.     register struct hnamemem *tp;
  761.  
  762.     for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != 0;
  763.          tp = tp->nxt)
  764.         if (tp->addr == dnaddr)
  765.             return (tp->name);
  766.  
  767.     tp->addr = dnaddr;
  768.     tp->nxt = (struct hnamemem *)calloc(1, sizeof(*tp));
  769.     if (nflag)
  770.         tp->name = dnnum_string(dnaddr);
  771.     else
  772.         tp->name = dnname_string(dnaddr);
  773.  
  774.     return(tp->name);
  775. }
  776.